package com.ea.dingtalk.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.dingtalkoauth2_1_0.Client;
import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest;

import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenResponse;
import com.aliyun.dingtalktodo_1_0.models.CreateTodoTaskHeaders;
import com.aliyun.dingtalktodo_1_0.models.CreateTodoTaskRequest;
import com.aliyun.tea.TeaException;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import com.ea.dingtalk.config.DingTalkConfig;
import com.ea.dingtalk.api.param.TodoTaskParam;
import com.ea.dingtalk.api.vo.AttendanceVO;
import com.ea.dingtalk.api.vo.DingTalkDeptVO;
import com.ea.dingtalk.api.vo.DingTalkUserBaseInfoVO;
import com.ea.util.StringUtil;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class DingTalkIntegrateService {

    /**
     * 获取钉钉AccessToken
     * @return
     */
    public String getAccessToken() {
        String appKey = DingTalkConfig.getAppKey();
        String appSecret = DingTalkConfig.getAppSecret();

        String corpId = DingTalkConfig.getCorpId();

        try {
            Config config = new Config();
            config.protocol="https";
            config.regionId="central";

            Client client = new Client(config);

            GetAccessTokenRequest getAccessTokenRequest = new GetAccessTokenRequest()
                    .setAppKey(appKey)
                    .setAppSecret(appSecret);

            GetAccessTokenResponse accessTokenResponse = client.getAccessToken(getAccessTokenRequest);

            String accessToken = accessTokenResponse.getBody().getAccessToken();
            return accessToken;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 查询当前用户信息（用于账号免登录接入）
     * @param code
     * @return
     */
    public Map<String,Object> getUserInfo(String code) {
        String accessToken = getAccessToken();
        Map<String,Object> userInfoMap = new HashMap<>();
        try {
            JSONObject paramJson = new JSONObject();
            paramJson.put("code", code);
            String userIdUrl = "https://oapi.dingtalk.com/topapi/v2/user/getuserinfo?access_token=" + accessToken;
            String userIdResult = HttpUtil.post(userIdUrl, paramJson.toString());
            JSONObject userIdInfo = JSONObject.parseObject(userIdResult);
            if (userIdInfo != null) {
                String resultcode = userIdInfo.getString("errcode");
                if (StringUtil.isNotEmpty(resultcode) && "0".equals(resultcode)) {
                    JSONObject resultJson = userIdInfo.getJSONObject("result");
                    if (resultJson != null) {
                        String userid = resultJson.getString("userid");
                        String name = resultJson.getString("name");
                        String unionid = resultJson.getString("unionid");
                        String device_id = resultJson.getString("device_id");
                        String associated_unionid = resultJson.getString("associated_unionid");
                        userInfoMap.put("code", "200");
                        userInfoMap.put("name", name);
                        userInfoMap.put("userid", userid);
                        userInfoMap.put("unionid", unionid);
                        userInfoMap.put("device_id", device_id);
                        userInfoMap.put("associated_unionid", associated_unionid);
                        if (StringUtil.isNotEmpty(userid)) {
                            // 根据userid查询用户信息https://oapi.dingtalk.com/topapi/v2/user/get
                            String userInfoUrl = "https://oapi.dingtalk.com/topapi/v2/user/get?access_token=" + accessToken;
                            JSONObject paramJson1 = new JSONObject();
                            paramJson1.put("userid", userid);
                            String userInfoResult = HttpUtil.post(userInfoUrl, paramJson1.toString());
                            JSONObject userInfoJson = JSONObject.parseObject(userInfoResult);
                            if (userInfoJson != null) {
                                String resultcode1 = userInfoJson.getString("errcode");
                                if (StringUtil.isNotEmpty(resultcode1) && "0".equals(resultcode1)) {
                                    JSONObject resultJson1 = userInfoJson.getJSONObject("result");
                                    if (resultJson1 != null) {
                                        String job_number = resultJson1.getString("job_number");
                                        String mobile = resultJson1.getString("mobile");
                                        String avatar = resultJson1.getString("avatar");
                                        userInfoMap.put("job_number", job_number);
                                        userInfoMap.put("mobile", mobile);
                                        userInfoMap.put("avatar", avatar);
                                    }
                                }
                            }
                        }

                    }
                }
            }
            return userInfoMap;
        } catch (Exception e) {
            userInfoMap.put("500", "钉钉AccessToken获取失败");
            e.printStackTrace();
        }
        return userInfoMap;
    }

    /**
     * 查询公司所有部门信息列表
     * @return
     */
    public List<DingTalkDeptVO> getAllDeptList(){
        List<DingTalkDeptVO> resultList = new ArrayList<>();
        String accessToken = getAccessToken();
        JSONObject paramJson = new JSONObject();
        paramJson.put("dept_id", 1);
        String deptListUrl = "https://oapi.dingtalk.com/topapi/v2/department/listsubid?access_token=" + accessToken;
        String deptList = HttpUtil.post(deptListUrl, paramJson.toString());
        JSONObject jsonObject = JSONObject.parseObject(deptList);
        if (jsonObject != null && "0".equals(jsonObject.getString("errcode"))) {
            JSONObject result = jsonObject.getJSONObject("result");
            JSONArray deptIdList = result.getJSONArray("dept_id_list");
            for (int i = 0; i < deptIdList.size(); i++) {
                DingTalkDeptVO dingTalkDeptVO = new DingTalkDeptVO();
                String deptId = deptIdList.getString(i);



                JSONObject deptParam = new JSONObject();
                deptParam.put("dept_id", deptId);
                String deptInfoUrl = "https://oapi.dingtalk.com/topapi/v2/department/get?access_token=" + accessToken;
                String deptInfo = HttpUtil.post(deptInfoUrl, deptParam.toString());

                JSONObject deptObject = JSONObject.parseObject(deptInfo);
                if (deptObject != null && "0".equals(deptObject.getString("errcode"))) {
                    JSONObject dept = deptObject.getJSONObject("result");
                    if (dept != null) {
                        dingTalkDeptVO.setDeptId(dept.getString("dept_id"));
                        dingTalkDeptVO.setName(dept.getString("name"));
                        dingTalkDeptVO.setParentId(dept.getString("parent_id"));
                        dingTalkDeptVO.setSourceIdentifier(dept.getString("source_identifier"));
                        dingTalkDeptVO.setCreateDeptGroup(dept.getBoolean("create_dept_group"));
                        dingTalkDeptVO.setAutoAddUser(dept.getBoolean("auto_add_user"));
                        dingTalkDeptVO.setAutoApproveApply(dept.getBoolean("auto_approve_apply"));
                        dingTalkDeptVO.setFromUnionOrg(dept.getBoolean("from_union_org"));
                        dingTalkDeptVO.setTags(dept.getString("tags"));
                        dingTalkDeptVO.setOrder(dept.getString("order"));
                        dingTalkDeptVO.setDeptGroupChatId(dept.getString("dept_group_chat_id"));
                        dingTalkDeptVO.setOrgDeptOwner(dept.getString("org_dept_owner"));
                        dingTalkDeptVO.setDeptManagerUseridList(dept.getString("dept_manager_userid_list"));
                        resultList.add(dingTalkDeptVO);
                    }
                }
            }
        }
        return resultList;
    }

    /**
     * 查询所有子部门列表信息
     * @param parentId
     * @return
     */
    public List<DingTalkDeptVO> getSubDeptList(String parentId){
        String accessToken = getAccessToken();
        JSONObject paramJson = new JSONObject();
        paramJson.put("dept_id", parentId);
        String deptListUrl = "https://oapi.dingtalk.com/topapi/v2/department/listsub?access_token=" + accessToken;
        String deptList = HttpUtil.post(deptListUrl, paramJson.toString());
        JSONObject jsonObject = JSONObject.parseObject(deptList);
        List<DingTalkDeptVO> resultList = new ArrayList<>();
        if (jsonObject != null && "0".equals(jsonObject.getString("errcode"))) {
            JSONArray result = jsonObject.getJSONArray("result");
            for (int i = 0; i < result.size(); i++) {
                DingTalkDeptVO dingTalkDeptVO = new DingTalkDeptVO();
                JSONObject deptJson = result.getJSONObject(i);
                String deptId = deptJson.getString("dept_id");
                String name = deptJson.getString("name");
                String pId = deptJson.getString("parent_id");
                Boolean createDeptGroup = deptJson.getBoolean("create_dept_group");
                Boolean autoAddUser = deptJson.getBoolean("auto_add_user");
                dingTalkDeptVO.setDeptId(deptId);
                dingTalkDeptVO.setName(name);
                dingTalkDeptVO.setParentId(pId);
                dingTalkDeptVO.setCreateDeptGroup(createDeptGroup);
                dingTalkDeptVO.setAutoAddUser(autoAddUser);
                resultList.add(dingTalkDeptVO);
                List<DingTalkDeptVO> subDeptList = this.getSubDeptList(deptId);
                resultList.addAll(subDeptList);
            }
        }
        return resultList;
    }

    /**
     * 查询所有用户信息
     * @return
     */
    public List<DingTalkUserBaseInfoVO> getAllUserBaseInfo(){
        String accessToken = getAccessToken();
        List<DingTalkUserBaseInfoVO> dingTalkUserBaseInfoVOList = new ArrayList<>();
        JSONObject paramJson = new JSONObject();
        paramJson.put("dept_id", 1);
        String deptListUrl = "https://oapi.dingtalk.com/topapi/v2/department/listsubid?access_token=" + accessToken;
        String deptList = HttpUtil.post(deptListUrl, paramJson.toString());
        JSONObject jsonObject = JSONObject.parseObject(deptList);
        if (jsonObject != null && "0".equals(jsonObject.getString("errcode"))) {
            JSONObject result = jsonObject.getJSONObject("result");
            JSONArray deptIdList = result.getJSONArray("dept_id_list");
            for (int i = 0; i < deptIdList.size(); i++) {
                DingTalkDeptVO dingTalkDeptVO = new DingTalkDeptVO();
                String deptId = deptIdList.getString(i);

                JSONObject deptParam = new JSONObject();
                deptParam.put("dept_id", deptId);
                String deptIdsUrl = "https://oapi.dingtalk.com/topapi/user/listid?access_token=" + accessToken;
                String userIdResult = HttpUtil.post(deptIdsUrl, deptParam.toString());

                JSONObject userIdObject = JSONObject.parseObject(userIdResult);
                if (userIdObject != null && "0".equals(userIdObject.getString("errcode"))) {
                    JSONObject userIds = userIdObject.getJSONObject("result");
                    if (userIds != null) {
                        JSONArray useridList = userIds.getJSONArray("userid_list");
                        for (int j = 0; j < useridList.size(); j++) {
                            String userId = useridList.getString(j);
                            if (StringUtil.isBlank(userId)) {
                                continue;
                            }

                            JSONObject userParam = new JSONObject();
                            userParam.put("userid", userId);
                            String userInfoUrl = "https://oapi.dingtalk.com/topapi/v2/user/get?access_token=" + accessToken;
                            String userInfo = HttpUtil.post(userInfoUrl, userParam.toString());

                            JSONObject userInfoJson = JSONObject.parseObject(userInfo);
                            if (userInfoJson != null && "0".equals(userInfoJson.getString("errcode"))) {
                                JSONObject userJson = userInfoJson.getJSONObject("result");
                                if (userJson != null) {
                                    DingTalkUserBaseInfoVO dingTalkUserBaseInfoVO = new DingTalkUserBaseInfoVO();
                                    dingTalkUserBaseInfoVO.setUserId(userJson.getString("userid"));
                                    dingTalkUserBaseInfoVO.setName(userJson.getString("name"));
                                    dingTalkUserBaseInfoVO.setUnionid(userJson.getString("unionid"));
                                    dingTalkUserBaseInfoVO.setAvatar(userJson.getString("avatar"));
                                    dingTalkUserBaseInfoVO.setStateCode(userJson.getString("state_code"));
                                    dingTalkUserBaseInfoVO.setManagerUserId(userJson.getString("manager_userid"));
                                    dingTalkUserBaseInfoVO.setMobile(userJson.getString("mobile"));
                                    dingTalkUserBaseInfoVO.setHideMobile(userJson.getBoolean("hide_mobile"));
                                    dingTalkUserBaseInfoVO.setTelephone(userJson.getString("telephone"));
                                    dingTalkUserBaseInfoVO.setJobNumber(userJson.getString("job_number"));
                                    dingTalkUserBaseInfoVO.setEmail(userJson.getString("email"));
                                    dingTalkUserBaseInfoVO.setWorkPlace(userJson.getString("work_place"));
                                    dingTalkUserBaseInfoVO.setExclusiveAccount(userJson.getBoolean("exclusive_account"));
                                    dingTalkUserBaseInfoVO.setOrgEmail(userJson.getString("org_email"));
                                    dingTalkUserBaseInfoVO.setDeptIdList(userJson.getString("dept_id_list"));
                                    dingTalkUserBaseInfoVO.setHiredDate(userJson.getDate("hired_date"));
                                    dingTalkUserBaseInfoVO.setActive(userJson.getBoolean("active"));
                                    dingTalkUserBaseInfoVO.setRealAuthed(userJson.getBoolean("real_authed"));
                                    dingTalkUserBaseInfoVO.setSenior(userJson.getBoolean("senior"));
                                    dingTalkUserBaseInfoVO.setAdmin(userJson.getBoolean("admin"));
                                    dingTalkUserBaseInfoVO.setBoss(userJson.getBoolean("boss"));
                                    dingTalkUserBaseInfoVOList.add(dingTalkUserBaseInfoVO);
                                }
                            }
                        }
                    }
                }
            }
        }
        return dingTalkUserBaseInfoVOList;
    }


    /**
     * 根据用户ID获取打卡结果（最多50个ID）
     * @param userIds
     * @return
     */
    public List<AttendanceVO> getAttendanceInfo(List<String> userIds){
        String accessToken = getAccessToken();
        List<AttendanceVO> attendanceVOList = new ArrayList<>();
        JSONObject paramJson = new JSONObject();
        paramJson.put("workDateFrom", DateUtil.beginOfDay(new Date()));
        paramJson.put("workDateTo", DateUtil.endOfDay(new Date()));
        paramJson.put("userIdList", userIds.toArray());
        paramJson.put("offset", 0);
        paramJson.put("limit", 50);
        String deptListUrl = "https://oapi.dingtalk.com/attendance/list?access_token=" + accessToken;
        String deptList = HttpUtil.post(deptListUrl, paramJson.toString());
        JSONObject jsonObject = JSONObject.parseObject(deptList);
        if (jsonObject != null && "0".equals(jsonObject.getString("errcode"))) {
            JSONArray resultArray = jsonObject.getJSONArray("recordresult");
            for (int i = 0; i < resultArray.size(); i++) {
                AttendanceVO attendanceVO = new AttendanceVO();
                JSONObject result = resultArray.getJSONObject(i);
                if (result != null) {
                    attendanceVO.setUserId(result.getString("userId"));
                    attendanceVO.setSourceType(result.getString("sourceType"));
                    attendanceVO.setBaseCheckTime(result.getDate("baseCheckTime"));
                    attendanceVO.setUserCheckTime(result.getDate("userCheckTime"));
                    attendanceVO.setProcInstId(result.getString("procInstId"));
                    attendanceVO.setApproveId(result.getString("approveId"));
                    attendanceVO.setLocationResult(result.getString("locationResult"));
                    attendanceVO.setTimeResult(result.getString("timeResult"));
                    attendanceVO.setCheckType(result.getString("checkType"));
                    attendanceVO.setWorkDate(result.getDate("workDate"));
                    attendanceVO.setRecordId(result.getString("recordId"));
                    attendanceVO.setPlanId(result.getString("planId"));
                    attendanceVO.setGroupId(result.getString("groupId"));
                    attendanceVO.setId(result.getString("id"));
                    attendanceVOList.add(attendanceVO);
                }
            }
        }
        return attendanceVOList;
    }


    /**
     * 发送待办消息
     * @return
     * @throws Exception
     */
    public String createTodoTask(TodoTaskParam param) throws Exception{
        String accessToken = getAccessToken();
        com.aliyun.dingtalktodo_1_0.Client client = createClient();
        CreateTodoTaskHeaders createTodoTaskHeaders = new CreateTodoTaskHeaders();
        createTodoTaskHeaders.xAcsDingtalkAccessToken = accessToken;
        CreateTodoTaskRequest.CreateTodoTaskRequestNotifyConfigs notifyConfigs = new CreateTodoTaskRequest.CreateTodoTaskRequestNotifyConfigs()
                .setDingNotify("1");
        CreateTodoTaskRequest.CreateTodoTaskRequestContentFieldList contentFieldList0 = new CreateTodoTaskRequest.CreateTodoTaskRequestContentFieldList();
        CreateTodoTaskRequest.CreateTodoTaskRequestDetailUrl detailUrl = new CreateTodoTaskRequest.CreateTodoTaskRequestDetailUrl()
                .setAppUrl(param.getAppUrl())
                .setPcUrl(param.getPcUrl());
        CreateTodoTaskRequest createTodoTaskRequest = new CreateTodoTaskRequest()
                .setOperatorId("PUoiinWIpxxx")  //当前操作者用户的unionId
                .setSourceId(param.getSourceId())       //业务系统侧的唯一标识ID，即业务ID
                .setSubject(param.getSubject())               //待办标题，最大长度1024
                .setCreatorId(param.getCreatorid())   //创建者的unionId
                .setDescription(param.getDescription())
                .setDueTime(param.getDueTime())                 //截止时间，Unix时间戳，单位毫秒
                .setExecutorIds(param.getExecutorIds())      //执行者的unionId，最大数量1000
                .setParticipantIds(param.getParticipantIds())      //参与者的unionId，最大数量1000
                .setDetailUrl(detailUrl)        //详情页url跳转地址
                .setContentFieldList(Arrays.asList(
                        contentFieldList0
                ))
                .setIsOnlyShowExecutor(param.getIsOnlyShowExecutor())        //生成的待办是否仅展示在执行者的待办列表中
                .setPriority(param.getPriority())                    //优先级，取值： 10：较低 20：普通 30：紧急 40：非常紧急
                .setNotifyConfigs(notifyConfigs);       //待办通知配置
        try {
            client.createTodoTaskWithOptions("PUoiinWIpa2yH2ymhiiGiP6g", createTodoTaskRequest, createTodoTaskHeaders, new RuntimeOptions());
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
            }

        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
            }
        }
        return "";
    }

    /**
     * 使用 Token 初始化账号Client
     * @return Client
     * @throws Exception
     */
    public static com.aliyun.dingtalktodo_1_0.Client createClient() throws Exception {
        Config config = new Config();
        config.protocol = "https";
        config.regionId = "central";
        return new com.aliyun.dingtalktodo_1_0.Client(config);
    }
}
